﻿#region ... Copyright Notice ...
/*
   Copyright 2008 Tyler Jensen

	Author: Tyler Jensen    http://www.tsjensen.com/blog

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */
#endregion

using System;
using System.Collections.Generic;
using System.Text;

namespace Atrax.Html
{
	public class ExtractedContent
	{
		public List<ContentSlice> Content = new List<ContentSlice>();
		public Dictionary<string, List<ContentSlice>> ClassifiedContent = new Dictionary<string, List<ContentSlice>>();
		public Dictionary<string, int> ClassMaxWordCount = new Dictionary<string, int>();
		public Dictionary<string, int> ClassMinWordCount = new Dictionary<string, int>();
		public Dictionary<string, int> ClassWordSum = new Dictionary<string, int>();
		public Dictionary<string, int> ClassWithWordsCount = new Dictionary<string, int>();
		public Dictionary<string, bool> ClassRelevant = new Dictionary<string, bool>();
		public Dictionary<string, PathToken> ClassPaths = new Dictionary<string, PathToken>();
		public List<string> ClassPathsSequence = new List<string>();
		public List<ContentSlice> ContentSequence = new List<ContentSlice>();
		public Dictionary<int, List<ContentSlice>> ContentBlocks = new Dictionary<int, List<ContentSlice>>();
		public Dictionary<int, List<string>> ContentBlocksTitleCase = new Dictionary<int, List<string>>();

		//TODO - add complete analysis algorithms here to extract zones or perhaps in a higher level

		public override string ToString()
		{
			StringBuilder sb = new StringBuilder();
			sb.AppendLine("= = = = = = = = = = = = = =");
			sb.AppendLine("avg   \tsum   \tmax   \tmin   \tcount   \trelevant   \tclass");

			foreach (KeyValuePair<string, int> item in ClassWordSum)
			{
				int max = ClassMaxWordCount[item.Key];
				int min = ClassMinWordCount[item.Key];
				int sum = item.Value;
				int count = ClassWithWordsCount[item.Key];
				double avg = count == 0 ? 0.0 : (double)sum / count;
				bool relevant = ClassRelevant[item.Key];
				sb.AppendLine(string.Format("{0}   \t{1}   \t{2}   \t{3}   \t{4}   \t{5}   \t{6}", avg.ToString("000.00"), sum, max, min, count, relevant, item.Key));
			}

			sb.AppendLine("= = = = = = = = = = = = = =");
			sb.AppendLine("count   \trelevant   \tclass path");
			foreach (KeyValuePair<string, PathToken> item in ClassPaths)
			{
				sb.AppendLine(string.Format("{0}   \t{1}   \t{2}", item.Value.Count, item.Value.RelevantCount, item.Key));
			}
			sb.AppendLine("= = = = = = = = = = = = = =");
			sb.AppendLine("class path sequence");
			foreach (string p in ClassPathsSequence)
			{
				sb.AppendLine(p);
			}
			sb.AppendLine("= = = = = = = = = = = = = =");

			foreach (KeyValuePair<int, List<ContentSlice>> item in ContentBlocks)
			{
				sb.AppendLine("# # # # # #");
				sb.AppendLine("Block #" + item.Key.ToString());
				sb.AppendLine("- - - - - - - - - - - -");
				foreach (ContentSlice s in item.Value)
				{
					if (s.Relevant) sb.AppendLine(s.Text);
				}
				sb.AppendLine("- - - - - - - - - - - -");
			}

			sb.AppendLine("= = = = = = = = = = = = = =");
			foreach (ContentSlice s in Content)
			{
				sb.AppendLine(s.ToString());
			}
			return sb.ToString();
		}
	}

	public class ContentSlice
	{
		public ContentSlice()
		{
			ImageCount = 0;
			ScriptCount = 0;
			BoldCount = 0;
			BRCount = 0;
			Level = 0;
			WordCount = 0;
			Relevant = true;
			FailureCode = string.Empty;
			DateText = string.Empty;
			ContainerDtdElement = DtdElement.BODY;
		}

		public ContentSlice Parent { get; set; }
		public List<ContentSlice> Content = new List<ContentSlice>();
		public string Class { get; set; }
		public string Path { get; set; }
		public string Text { get; set; }
		public int Level { get; set; }
		public int InternalLinkCount { get; set; }
		public int ExternalLinkCount { get; set; }
		public int ImageCount { get; set; }
		public int ScriptCount { get; set; }
		public int BoldCount { get; set; }
		public int BRCount { get; set; }
		public int WordCount { get; set; }
		public bool Relevant { get; set; }
		public string FailureCode { get; set; }
		public string DateText { get; set; }
		public DtdElement ContainerDtdElement { get; set; }

		public override string ToString()
		{
			StringBuilder sb = new StringBuilder();
			sb.AppendLine("+ + + + + + + + + + + + + + + + + + + + + + + +");
			sb.AppendLine("class := " + Class);
			sb.AppendLine("path := " + Path);
			sb.AppendLine("level := " + Level);
			sb.AppendLine("relevant := " + Relevant.ToString());
			if (Relevant == false)
				sb.AppendLine("failure code := " + FailureCode);
			sb.AppendLine("dtd := " + ContainerDtdElement.ToString());
			sb.AppendLine("internal link count := " + InternalLinkCount.ToString());
			sb.AppendLine("external link count := " + ExternalLinkCount.ToString());
			sb.AppendLine("image count := " + ImageCount.ToString());
			sb.AppendLine("script count := " + ScriptCount.ToString());
			sb.AppendLine("bold count := " + BoldCount.ToString());
			sb.AppendLine("BR count := " + BRCount.ToString());
			sb.AppendLine("inner content count := " + Content.Count.ToString());
			sb.AppendLine("text := " + Text);
			sb.AppendLine("- - - - - - - - - - - - - - - - - - - - - - - -");
			foreach (ContentSlice s in Content)
			{
				sb.AppendLine(s.ToString());
			}
			sb.AppendLine("+ + + + + + + + + + + + + + + + + + + + + + + +");
			return sb.ToString();
		}
	}
}
